package com.eastdigit.system.service;

import com.eastdigit.servlet.ReqBean;
import com.eastdigit.system.inter.RoleMapper;
import com.eastdigit.system.inter.RoleMenuMapper;
import com.eastdigit.system.model.*;
import com.eastdigit.util.StringUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class RoleService extends BaseService implements IRoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private IUserService userService;
    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private DataScopeService dataScopeService;

    /**
     * 查询角色，返回JSONArray
     * 
     * @param reqBean
     * @return 返回JSONArray
     */
    @Override
    public JSONObject queryTable(ReqBean reqBean) {
        String deptId = reqBean.getInfo("deptId");

        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.appendSql("select ROLE_ID, ROLE_NAME, C_ROLE_SCOPE, REMARK, DEPT_ID,")
                .appendSql(" (select DEPT_NAME from SYS_DEPARTMENT where DEPT_ID = a.DEPT_ID) \"deptName\" ")
                .appendSql(" from SYS_ROLE a where 1=1 ").addWhereDataScope("a.DEPT_ID", reqBean);

        if (StringUtil.isNotEmpty(deptId)) {
            List<Object> list = new ArrayList<Object>();
            List<IDepartment> departments = departmentService.queryDescendantDepartmentAndSelf(deptId);
            for (IDepartment department : departments) {
                list.add(department.getDeptId());
            }
            sqlBuilder.addWhereIn("DEPT_ID", list);
        }
        sqlBuilder.orderBy("order by DEPT_ID");

        return queryTable(sqlBuilder, reqBean.getPageSize(), reqBean.getPageIndex());
    }

    /**
     * 角色树
     * 
     * @param userId
     * @return 当前用户所属部门及以下部门的角色
     */
    @Override
    public JSONArray queryRoleTree(String userId) {
        IUser user = userService.queryById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在！");
        }
        Map<String, IDepartment> map = new HashMap<String, IDepartment>();
        List<IDepartment> list = departmentService.queryDescendantDepartmentAndSelf(user.getDeptId());
        List<Object> params = new ArrayList<Object>();
        for (IDepartment department : list) {
            map.put(department.getDeptId(), department);
            params.add(department.getDeptId());
        }

        JSONArray array = query(new SqlBuilder(
                "select ROLE_ID, DEPT_ID, ROLE_NAME, C_ROLE_SCOPE from SYS_ROLE a where 1 = 1").addWhereIn("a.DEPT_ID",
                params));
        for (int i = 0, size = array.size(); i < size; i++) {// 这里循环时array的size会变化
            JSONObject json = array.getJSONObject(i);
            // json.put("roleId", role.getId());
            // json.put("roleName", role.getName());
            // json.put("deptId", role.getDeptId());
            json.put("id", json.getString("roleId"));
            json.put("name", json.getString("roleName"));
            json.put("parentId", "dept-" + json.getString("deptId"));
            // array.add(json);
            addParentDept(map.get(json.getString("deptId")), array, map);
        }
        return array;
    }

    private void addParentDept(IDepartment department, JSONArray array, Map<String, IDepartment> map) {
        if (department != null && !map.containsKey("D" + department.getDeptId())) {
            JSONObject json = new JSONObject();
            json.put("roleId", "");
            json.put("deptId", department.getDeptId());
            json.put("id", "dept-" + department.getDeptId());
            json.put("name", department.getDeptName());
            json.put("parentId", "dept-" + department.getParentDeptId());
            array.add(json);
            map.put("D" + department.getDeptId(), department);// 避免重复添加

            addParentDept(map.get(department.getParentDeptId()), array, map);
        }

    }

    /**
     * 通过id查找
     * 
     * @param roleId
     * @return
     */
    @Override
    public Role queryById(String roleId) {
        return roleMapper.selectByPrimaryKey(roleId);
    }

    /**
     * 新增角色
     * 
     * @param role
     */
    @Override
    public void add(Role role) {
        role.setId(intIncrementId("SYS_ROLE", "ROLE_ID"));// 手动设置Id
        role.setMakeTime(new Date());
        role.setModifyTime(role.getMakeTime());
        roleMapper.insert(role);
    }

    /**
     * 修改角色
     * 
     * @param role
     */
    @Override
    public void update(Role role) {
        String roleId = role.getId();
        if (StringUtil.isEmpty(roleId)) {
            throw new BusinessException("获取主键失败");
        }
        // 修改数据范围表，这里要先执行
        dataScopeService.updateByRoleUpdate(roleId, role.getScope());
        roleMapper.updateByPrimaryKeySelective(role);
    }

    /**
     * 删除角色
     * 
     * @param roleId
     */
    @Override
    public void delete(String roleId) {
        // String roleId = role.getId();
        if (StringUtil.isEmpty(roleId)) {
            throw new BusinessException("获取主键失败");
        }

        // 修改数据范围表，这里要先执行
        dataScopeService.updateByRoleDelete(roleId);
        // 删除用户关联该角色
        userRoleService.delUserRoleOfRole(roleId);
        // 删除角色关联菜单
        roleMenuMapper.deleteByRoleId(roleId);

        roleMapper.deleteByPrimaryKey(roleId);
    }

    /**
     * 删除角色，这里不考虑子部门的问题
     * 
     * @param deptId
     */
    @Override
    public void deleteByDeptId(String deptId) {
        // String roleId = role.getId();
        if (StringUtil.isEmpty(deptId)) {
            throw new BusinessException("获取部门失败");
        }

        List<Role> list = roleMapper.selectRoleOfDept(deptId);
        for (Role role : list) {
            String roleId = role.getId();
            // 修改数据范围表，这里要先执行
            // dataScopeService.updateByRoleDelete(roleId);
            // 删除用户关联该角色
            userRoleService.delUserRoleOfRole(roleId);
            // 删除角色关联菜单
            roleMenuMapper.deleteByRoleId(roleId);

            roleMapper.deleteByPrimaryKey(roleId);
        }
    }

    /**
     * 查询[角色-菜单]关系
     * 
     * @param roleId
     * @return
     */
    @Override
    public List<RoleMenu> queryRoleMenu(String roleId) {
        return roleMenuMapper.queryRoleMenu(roleId);
    }

    /**
     * 新增[角色-菜单]关系
     * 
     * @param roleId
     * @param menuIds
     */
    @Override
    public void addRoleMenu(String roleId, String menuIds) {
        if (StringUtils.isNotBlank(menuIds)) {
            String[] menuIdArr = menuIds.split(",");
            for (String menuId : menuIdArr) {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setMenuId(menuId);
                roleMenu.setRoleId(roleId);
                roleMenuMapper.insert(roleMenu);
            }

            // 修改数据范围表
            dataScopeService.updateByRoleAddMenus(roleId, menuIds);
        }
    }

    /**
     * 删除[角色-菜单]关系
     * 
     * @param roleId
     * @param menuIds
     */
    @Override
    public void deleteRoleMenu(String roleId, String menuIds) {
        if (StringUtils.isNotBlank(menuIds)) {
            // 修改数据范围表，这里要先执行
            dataScopeService.updateByRoleDeleteMenus(roleId, menuIds);

            String[] menuIdArr = menuIds.split(",");
            for (String menuId : menuIdArr) {
                roleMenuMapper.deleteByPrimaryKey(roleId, menuId);
            }
        }
    }

    /**
     * 查询用户所拥有的角色
     * 
     * @param userId
     * @return
     */
    @Override
    public List<Role> queryRoleOfUser(String userId) {
        return roleMapper.selectRoleOfUser(userId);
    }

}
